﻿' •————————————————————————————————————————————————————————————————————————————————————————————————————————————•
' |                                                                                                            |
' |    GeoLock is a proof of concept (PoC). GeoLock uses Geosense for Windows,                                 |
' |    Microsoft Windows 7 Sensor and Location Interop Sample Library, Microsoft WindowsAPICodePack            |
' |    and Microsoft Bing Maps SDK to demonstrate how to retrieve geolocation data without                     |
' |    Global Positioning System (GPS) hardware.                                                               |
' |                                                                                                            |
' |    The GeoLocK application was written in VB.NET (WPF). The COM Interop Windows7.SensorAndLocation.dll,    |
' |    Microsoft.WindowsAPICodePack.dll and Microsoft.Maps.MapControl.WPF.dll supplied                         |
' |    with this application are x86 binaries.                                                                 |
' |                                                                                                            |
' |    Copyright (C) 2012 Pascal Hubert aka Néo <http://geolock.codeplex.com/>                                 |
' |                                                                                                            |
' |    Project administrator : Pascal Hubert aka Néo (neojudgment@hotmail.com)                                 |
' |                                                                                                            |
' |    This program is under Microsoft Public License (Ms-PL)                                                  |
' |                                                                                                            |
' |    You should have received a copy of the Microsoft Public License (Ms-PL)                                 |
' |    along with this program.  If not, see <http://msdn.microsoft.com/en-us/library/ff647936.aspx>.          |
' |                                                                                                            |
' •————————————————————————————————————————————————————————————————————————————————————————————————————————————•
Imports System.IO
Imports System.IO.Ports
Imports System.Threading

Public Class Settings
    Private Shared WithEvents _spa As SerialPort
    Public Shared GeolockUpdate As Boolean
    Public Shared Update As Boolean
    Public Shared SaveChange As Boolean
    Public Shared ComPortScan As Boolean
    Public Shared ComPortDiscovered As Integer

    Public Sub New()

        InitializeComponent()

        Top = Application.Current.MainWindow.Top
        Left = Application.Current.MainWindow.Left

        ShowComports()

        With My.Settings
            If .ProxyPort > 0 Then
                TextBoxProxyAdress.Text = .ProxyAdress
                TextBoxProxyPort.Text = CStr(.ProxyPort)
                TextBoxUsername.Text = .ProxyUsername
                PasswordBox.Password = .ProxyPassword
            End If

            If .UseHttps Then
                CheckBoxUseSSL.IsChecked = True
            Else
                CheckBoxUseSSL.IsChecked = False
            End If

            If .UseGpsHarware Then
                CheckBoxGpsHardware.IsChecked = True
            Else
                CheckBoxGpsHardware.IsChecked = False
            End If

            If .AutoUpdate Then
                CheckBoxUpdates.IsChecked = True
            Else
                CheckBoxUpdates.IsChecked = False
            End If

            If .Hemisphere Then
                CheckBoxHemisphere.IsChecked = True
            Else
                CheckBoxHemisphere.IsChecked = False
            End If

            ComboBoxComPort.Text = CType(.ComPort, String)
            ComboBoxSpeed.Text = CType(.ComSpeed, String)
            TextBoxBingMapKey.Text = .BingMapKey
        End With
    End Sub

    Private Sub ButtonCancelChangesClick(sender As Object, e As RoutedEventArgs) Handles ButtonCancelChanges.Click

        Trace.WriteLine(DateTime.Now & " " & "ButtonCancelChangesClick")

        MainWindow.FormTop = Top
        MainWindow.FormLeft = Left
        Close()
    End Sub

    Private Sub ButtonSaveChangesClick(sender As Object, e As RoutedEventArgs) Handles ButtonSaveChanges.Click

        Trace.WriteLine(DateTime.Now & " " & "ButtonSaveChangesClick")

        With My.Settings
            ' Le Proxy est utilisé
            If .UseProxy Then
                ' L'adresse proxy contient "http://"
                If TextBoxProxyAdress.Text.ToLower.Contains("http://") Then
                    ' Le port du Proxy n'est pas vide est contient du numérique
                    If (Not String.IsNullOrEmpty(TextBoxProxyPort.Text)) AndAlso IsNumeric(TextBoxProxyPort.Text) Then
                        .ProxyPort = CInt(TextBoxProxyPort.Text)
                        .ProxyAdress = TextBoxProxyAdress.Text
                        .ProxyUsername = TextBoxUsername.Text
                        .ProxyPassword = PasswordBox.Password
                    Else
                        ' Si le port du Proxy est vide on le met à 0
                        If (String.IsNullOrEmpty(TextBoxProxyPort.Text)) Then
                            .ProxyPort = 0
                        End If
                    End If
                End If
            End If

            If CheckBoxUseSSL.IsChecked Then
                .UseHttps = True
            Else
                .UseHttps = False
            End If

            If CheckBoxProxyAuthentication.IsChecked Then
                .UseProxy = True
            Else
                .UseProxy = False
            End If

            If CheckBoxGpsHardware.IsChecked Then
                .UseGpsHarware = True
            Else
                .UseGpsHarware = False
            End If

            If CheckBoxUpdates.IsChecked Then
                .AutoUpdate = True
            Else
                .AutoUpdate = False
            End If

            If CheckBoxHemisphere.IsChecked Then
                .Hemisphere = True
            Else
                .Hemisphere = False
            End If

            .ComPort = CType(ComboBoxComPort.Text, Integer)
            .ComSpeed = CType(ComboBoxSpeed.Text, Integer)
            .BingMapKey = TextBoxBingMapKey.Text

            SaveChange = True
            .Save()

            Dim newform As New Message
            newform.Owner = Me
            newform.ShowDialog()
        End With

        MainWindow.FormTop = Top
        MainWindow.FormLeft = Left
        Close()
    End Sub

    Private Sub ShowComports()

        ComboBoxComPort.Items.Clear()
        For Each sp As String In My.Computer.Ports.SerialPortNames
            ComboBoxComPort.Items.Add(sp.ToString().Replace("COM", ""))
        Next sp

        If ComboBoxComPort.Items.Count > 0 Then
            ComboBoxComPort.SelectedIndex = ComboBoxComPort.Items.Count - 1
            ComboBoxSpeed.SelectedIndex = 2
        End If
    End Sub

    Private Sub ButtonSoftwareUpdateClick(sender As System.Object, e As RoutedEventArgs) Handles ButtonSoftwareUpdate.Click

        MainWindow.XmlParser()

        Update = True

        Dim newform As New Message
        newform.Owner = Me
        newform.ShowDialog()
    End Sub

    Private Sub ButtonHardwareDetectClick(sender As System.Object, e As RoutedEventArgs) Handles ButtonHardwareDetect.Click

        ComPortScan = True

        Dim newform As New Message

        ' Message de confirmation du scan
        newform.Owner = Me
        newform.ShowDialog()

        ComPortScan = False

        If Message.MustScan Then

            ' Message durant le scan
            newform = New Message
            newform.Owner = Me
            newform.Show()

            ' On lance le scan
            Dim myport As String = ScanPorts()

            newform.Close()
            Message.MustScan = False

            ' GPS non trouvé 
            If myport = "" Then

                ' Message GPS non trouvé 
                ComPortDiscovered = 2
                newform = New Message
                newform.Owner = Me
                newform.ShowDialog()
                Return
            Else
                ' GPS trouvé
                ComPortDiscovered = 1
                My.Settings.ComPort = CInt((myport.Substring(myport.Length - 1)))
                ComboBoxComPort.Text = CInt((myport.Substring(myport.Length - 1))).ToString()
                My.Settings.Save()

                ' Message GPS trouvé + COM
                newform = New Message
                newform.Owner = Me
                newform.ShowDialog()
                ComPortDiscovered = 0
            End If
        End If
    End Sub

    Private Shared Function ScanPorts() As String

        Try
            For Each port As String In SerialPort.GetPortNames
                Try
                    If CheckPortForGps(port) Then
                        Return port
                    End If
                Catch ex As IOException
                End Try
            Next port

            Return ""

        Catch ex As Exception
            Return ""
        End Try
    End Function

    Private Shared Function CheckPortForGps(ByVal port As String) As Boolean

        Dim testData As String
        Dim i As Integer

        Try
            _spa = New SerialPort(port, My.Settings.ComSpeed, Parity.None, 8, StopBits.One)

            If _spa.IsOpen Then
                Return False
            End If

            _spa.ReadBufferSize = 4096
            _spa.Open()

            If _spa.IsOpen Then
                ' On fait 2 essais du même port
                For i = 1 To 2
                    Thread.Sleep(1000)
                    testData = _spa.ReadExisting()
                    If testData.Contains("$GPGGA") OrElse testData.Contains("$GPVTG") Then

                        _spa.Close()

                        Return True
                    End If
                Next i
                _spa.Close()
            End If
            Return False
        Catch ex As IOException
            Return False
        End Try
    End Function

    Private Shared Sub SerialPortErrorReceived(ByVal sender As Object, ByVal e As SerialErrorReceivedEventArgs) Handles _spa.ErrorReceived

        ' Erreurs de réception
        Console.WriteLine(e.EventType.ToString)
        Trace.WriteLine(DateTime.Now & " " & "SerialPortErrorReceived: " & e.EventType.ToString)
    End Sub

    Private Sub SettingsClosing(sender As Object, e As ComponentModel.CancelEventArgs) Handles Me.Closing

        MainWindow.FormTop = Top
        MainWindow.FormLeft = Left
    End Sub

    Private Sub SettingsLoaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

        Activate()

        Application.Current.MainWindow.Left = SystemParameters.PrimaryScreenWidth - 5000
        Application.Current.MainWindow.Top = SystemParameters.PrimaryScreenHeight - 5000
    End Sub

    Private Sub SettingsLocationChanged(sender As Object, e As EventArgs) Handles Me.LocationChanged

        MainWindow.MyWindowMove = True
    End Sub
End Class
